package gxprod.androidai;

import gxprod.androidai.regex.MatchResult;
import gxprod.androidai.regex.NamedMatcher;
import gxprod.androidai.regex.NamedPattern;

/**
 * Basically a question, and the appropriate response.
 * @author Josh Maleszewski
 */
public  class Question {

	public Response Response;
	public AnswerReciever Invoke;
	public String onCancel;
	public String Query;
	public Object Tag;

	public Question(String query, Response response, AnswerReciever invoke, Object tag) {
		this(query, invoke, tag);
		Response = response;
	}

	public Question(String query, AnswerReciever invoke, Object tag) {
		Invoke = invoke;
		Tag = tag;
		Query = query;
	}

	public void process(String command, BubbleAdapter adapter) {
		if(Response.isValidResponse(command))
			Invoke.onAnswer(command, this, Response, adapter);
		else
			adapter.output("Invalid Response", "");
	}

	public String onCancelSay() { return onCancel; }

	public static abstract class Response {
		public abstract boolean isValidResponse(String answer);
	}

	public  class ChoiceResponse extends Response {
		public String[] Choices;
		public String[] Patterns;
		public int Default;
		public int Selected;		

		public ChoiceResponse(String[] choices, String[] patterns, int def) {
			Choices = choices;
			Patterns = patterns;
			Default = def;
			Selected = -1;
		}
		@Override
		public boolean isValidResponse(String answer) {
			for(int i = 0; i < Choices.length; i++) 
				if(Choices[i].equals(answer)) {
					Selected = i;
					return true;
				}
			NamedMatcher matcher = new NamedMatcher();
			for(int i = 0; i < Patterns.length; i++) {
				NamedPattern p = NamedPattern.compile(Patterns[i]);
				matcher = matcher.usePattern(p);
				if(matcher.find()) 
					return true;
			}
			Selected = -1;
			return false;
		}

		public MatchResult getMatch(String a) {
			NamedMatcher matcher = new NamedMatcher();
			for(int i = 0; i < Patterns.length; i++) {
				NamedPattern p = NamedPattern.compile(Patterns[i]);
				matcher = matcher.usePattern(p);
				if(matcher.find()) 
					return new MatchResult(matcher, i, 0.0f, null);
			}
			return new MatchResult();

		}
	}

	public class YesNoResponse extends ChoiceResponse {
		public YesNoResponse(int def) {
			super(new String[] { "Yes", "No" }, new String[] { "(yes|ya|right)", "(no|na|nope|wrong)" }, def);
		}
	}

	/**
	 * Accepts numbers as a response
	 * @author Josh Maleszewski
	 */
	public class NumberResponse extends Response {
		public boolean Decimal;
		@Override
		public boolean isValidResponse(String answer) {
			try {
				if(Decimal)
					Double.valueOf(answer);
				else
					Long.valueOf(answer);
				return true;
			}catch(Exception ex) {
				return false;
			}
		}
	}
}
